<template>
  <div class="app-container">
    <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
      <el-form-item label="活动标题" prop="title">
        <el-input
            v-model="queryParams.title"
            placeholder="请输入活动标题"
            clearable
            @keyup.enter="handleQuery"
        />
      </el-form-item>
      <el-form-item label="主办方" prop="organizer">
        <el-input
            v-model="queryParams.organizer"
            placeholder="请输入主办方"
            clearable
            @keyup.enter="handleQuery"
        />
      </el-form-item>
      <el-form-item label="报名开始时间" label-width="120px" style="width: 308px">
        <el-date-picker
            v-model="daterangeRegistrationStartTime"
            value-format="YYYY-MM-DD"
            type="daterange"
            range-separator="-"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
        />
      </el-form-item>
      <el-form-item label="报名结束时间" label-width="120px" style="width: 308px">
        <el-date-picker
            v-model="daterangeRegistrationEndTime"
            value-format="YYYY-MM-DD"
            type="daterange"
            range-separator="-"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
        />
      </el-form-item>
      <el-form-item label="类型" prop="typeId">
        <el-cascader
            v-model="queryParams.typeId"
            :options="activityTypeTree"
            :props="cascaderProps"
            clearable
            filterable
            style="width: 240px"
            placeholder="请选择类型"
        />
      </el-form-item>
      <el-form-item label="状态" prop="status">
        <el-select v-model="queryParams.status" placeholder="请选择状态" clearable>
          <el-option
              v-for="dict in sys_common_status"
              :key="dict.value"
              :label="dict.label"
              :value="dict.value"
          />
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
        <el-button icon="Refresh" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
            type="primary"
            plain
            icon="Plus"
            @click="handleAdd"
            v-hasPermi="['activity:activity:add']"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
            type="success"
            plain
            icon="Edit"
            :disabled="single"
            @click="handleUpdate"
            v-hasPermi="['activity:activity:edit']"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
            type="danger"
            plain
            icon="Delete"
            :disabled="multiple"
            @click="handleDelete"
            v-hasPermi="['activity:activity:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
            type="warning"
            plain
            icon="Download"
            @click="handleExport"
            v-hasPermi="['activity:activity:export']"
        >导出</el-button>
      </el-col>
      <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>

    <el-table v-loading="loading" :data="activityList" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="活动ID" align="center" prop="id" />
      <el-table-column label="活动标题" align="center" prop="title" />
      <el-table-column label="主办方" align="center" prop="organizer" />
      <el-table-column label="报名开始时间" align="center" prop="registrationStartTime" width="180">
        <template #default="scope">
          <span>{{ parseTime(scope.row.registrationStartTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
        </template>
      </el-table-column>
      <el-table-column label="报名结束时间" align="center" prop="registrationEndTime" width="180">
        <template #default="scope">
          <span>{{ parseTime(scope.row.registrationEndTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
        </template>
      </el-table-column>
      <el-table-column label="活动开始时间" align="center" prop="startTime" width="180">
        <template #default="scope">
          <span>{{ parseTime(scope.row.startTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
        </template>
      </el-table-column>
      <el-table-column label="活动结束时间" align="center" prop="endTime" width="180">
        <template #default="scope">
          <span>{{ parseTime(scope.row.endTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
        </template>
      </el-table-column>
      <el-table-column label="类型" align="center">
        <template #default="scope">
          {{ getFullTypePath(scope.row.typeId) }}
        </template>
      </el-table-column>
      <el-table-column label="创建人ID" align="center" prop="creatorId" />
      <el-table-column label="封面图" align="center" prop="coverImageUrl" width="100">
        <template #default="scope">
          <image-preview :src="scope.row.coverImageUrl" :width="50" :height="50"/>
        </template>
      </el-table-column>
      <el-table-column label="官网链接" align="center" prop="websiteUrl" />
      <el-table-column label="介绍" align="center" width="100">
        <template #default="scope">
          <el-button link type="primary" @click="handleViewContent(scope.row.content)">查看介绍</el-button>
        </template>
      </el-table-column>
      <el-table-column label="状态" align="center" prop="status">
        <template #default="scope">
          <dict-tag :options="sys_common_status" :value="scope.row.status"/>
        </template>
      </el-table-column>
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="160">
        <template #default="scope">
          <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['activity:activity:edit']">修改</el-button>
          <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['activity:activity:remove']">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <pagination
        v-show="total > 0"
        :total="total"
        v-model:page="queryParams.pageNum"
        v-model:limit="queryParams.pageSize"
        @pagination="getList"
    />

    <!-- 新增/修改对话框 -->
    <el-dialog
        :title="title"
        v-model="open"
        width="800px"
        class="custom-dialog"
        append-to-body
        @closed="handleDialogClosed"
    >
      <el-form ref="activityRef" :model="form" :rules="rules" label-width="100px">
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="活动标题" prop="title">
              <el-input v-model="form.title" placeholder="请输入活动标题" />
            </el-form-item>
            <el-form-item label="主办方" prop="organizer">
              <el-input v-model="form.organizer" placeholder="请输入主办方" />
            </el-form-item>
            <el-form-item label="报名时间" required>
              <div class="date-range">
                <el-form-item prop="registrationStartTime">
                  <el-date-picker
                      v-model="form.registrationStartTime"
                      type="datetime"
                      placeholder="开始时间"
                      format="YYYY-MM-DD HH:mm:ss"
                      value-format="YYYY-MM-DD HH:mm:ss"
                      :disabled-date="disabledRegistrationStartDate"
                      class="w-full"
                  />
                </el-form-item>
                <el-form-item prop="registrationEndTime">
                  <el-date-picker
                      v-model="form.registrationEndTime"
                      type="datetime"
                      placeholder="结束时间"
                      format="YYYY-MM-DD HH:mm:ss"
                      value-format="YYYY-MM-DD HH:mm:ss"
                      :disabled="!form.registrationStartTime"
                      :disabled-date="disabledRegistrationEndDate"
                      class="w-full"
                  />
                </el-form-item>
              </div>
            </el-form-item>
            <el-form-item label="活动时间" required>
              <div class="date-range">
                <el-form-item prop="startTime">
                  <el-date-picker
                      v-model="form.startTime"
                      type="datetime"
                      placeholder="开始时间"
                      format="YYYY-MM-DD HH:mm:ss"
                      value-format="YYYY-MM-DD HH:mm:ss"
                      class="w-full"
                  />
                </el-form-item>
                <el-form-item prop="endTime">
                  <el-date-picker
                      v-model="form.endTime"
                      type="datetime"
                      placeholder="结束时间"
                      format="YYYY-MM-DD HH:mm:ss"
                      value-format="YYYY-MM-DD HH:mm:ss"
                      :disabled="!form.startTime"
                      :disabled-date="(date) => date < form.startTime"
                      class="w-full"
                  />
                </el-form-item>
              </div>
            </el-form-item>
          </el-col>

          <el-col :span="12">
            <el-form-item label="活动类型" prop="typeId">
              <el-cascader
                  v-model="form.typeId"
                  :options="activityTypeTree"
                  :props="cascaderProps"
                  placeholder="请选择类型"
                  class="w-full"
              />
            </el-form-item>
            <el-form-item label="封面图" prop="coverImageUrl">
              <image-upload v-model="form.coverImageUrl" />
            </el-form-item>
            <el-form-item label="状态" prop="status">
              <el-radio-group v-model="form.status">
                <el-radio
                    v-for="dict in sys_common_status"
                    :key="dict.value"
                    :label="dict.value"
                    border
                >{{ dict.label }}</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>

        <el-form-item label="官网链接" prop="websiteUrl">
          <el-input v-model="form.websiteUrl" placeholder="请输入官网链接" />
        </el-form-item>

        <el-form-item label="活动介绍" prop="content">
          <editor
              ref="editorRef"
              v-model="form.content"
              :min-height="200"
              class="rich-editor"
              placeholder="请输入活动详细介绍..."
          />
        </el-form-item>
      </el-form>

      <template #footer>
        <div class="dialog-footer">
          <el-button @click="cancel">取 消</el-button>
          <el-button type="primary" @click="submitForm">确 定</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 查看介绍弹窗 -->
    <el-dialog
        v-model="contentDialogVisible"
        title="活动详情介绍"
        width="800px"
        class="markdown-dialog"
        append-to-body
    >
      <div class="markdown-content custom-scrollbar" v-html="formattedContent"></div>
    </el-dialog>
  </div>
</template>

<script setup>
import { getCurrentInstance, ref, reactive, onMounted, computed, nextTick } from 'vue'
import { listActivity, getActivity, delActivity, addActivity, updateActivity } from "@/api/activity/activity"
import { listActivityType } from "@/api/activityType/activityType"
import { marked } from 'marked'
import DOMPurify from 'dompurify'
import dayjs from 'dayjs'

const { proxy } = getCurrentInstance()
const { sys_common_status } = proxy.useDict('sys_common_status')

// 响应式数据
const activityList = ref([])
const activityTypeTree = ref([])
const typePathMap = ref({})
const loading = ref(true)
const showSearch = ref(true)
const open = ref(false)
const contentDialogVisible = ref(false)
const currentContent = ref('')
const ids = ref([])
const single = ref(true)
const multiple = ref(true)
const total = ref(0)
const title = ref("")
const daterangeRegistrationStartTime = ref([])
const daterangeRegistrationEndTime = ref([])
const editorRef = ref(null)
const dialogKey = ref(0)
const editorKey = ref(0)

const cascaderProps = {
  value: 'id',
  label: 'name',
  children: 'children',
  checkStrictly: true,
  emitPath: false,
  expandTrigger: 'hover'
}

// 表单默认值
const formDefaults = () => ({
  id: null,
  title: null,
  organizer: null,
  registrationStartTime: null,
  registrationEndTime: null,
  startTime: null,
  endTime: null,
  typeId: null,
  creatorId: null,
  coverImageUrl: null,
  websiteUrl: null,
  content: null,
  status: '0'
})

const data = reactive({
  form: formDefaults(),
  queryParams: {
    pageNum: 1,
    pageSize: 10,
    title: null,
    organizer: null,
    registrationStartTime: null,
    registrationEndTime: null,
    typeId: null,
    status: null,
    params: {
      beginRegistrationStartTime: null,
      endRegistrationStartTime: null,
      beginRegistrationEndTime: null,
      endRegistrationEndTime: null
    }
  },
  rules: {
    title: [{ required: true, message: "活动标题不能为空", trigger: "blur" }],
    typeId: [{
      required: true,
      validator: (rule, value, callback) => {
        if (!value) return callback(new Error("请选择类型"))
        const findLeafNode = (tree) => {
          for (const node of tree) {
            if (node.id === value) return node.children?.length ? null : node
            if (node.children) {
              const found = findLeafNode(node.children)
              if (found) return found
            }
          }
          return null
        }
        const target = findLeafNode(activityTypeTree.value)
        target?.children?.length
            ? callback(new Error("请选择最后一级分类"))
            : callback()
      },
      trigger: ['blur', 'change']
    }],
    registrationStartTime: [
      { required: true, message: '请选择报名开始时间', trigger: 'change' }
    ],
    registrationEndTime: [
      {
        required: true,
        validator: (rule, value, callback) => {
          if (!value) return callback(new Error('请选择报名结束时间'))
          if (new Date(value) <= new Date(data.form.registrationStartTime)) {
            callback(new Error('结束时间必须晚于开始时间'))
          } else {
            callback()
          }
        },
        trigger: 'change'
      }
    ],
    startTime: [
      { required: true, message: '请选择活动开始时间', trigger: 'change' }
    ],
    endTime: [
      {
        required: true,
        validator: (rule, value, callback) => {
          if (!value) return callback(new Error('请选择活动结束时间'))
          if (new Date(value) <= new Date(data.form.startTime)) {
            callback(new Error('活动结束时间必须晚于开始时间'))
          } else {
            callback()
          }
        },
        trigger: 'change'
      }
    ]
  }
})

const { queryParams, form, rules } = toRefs(data)

// 日期处理
const formatDateString = (dateStr) => {
  if (!dateStr) return null
  return dayjs(dateStr).isValid()
      ? dayjs(dateStr).format('YYYY-MM-DD HH:mm:ss')
      : null
}

// 日期禁用规则
const disabledRegistrationStartDate = (time) => {
  return time < Date.now() - 86400000 // 禁用过去时间
}

const disabledRegistrationEndDate = (time) => {
  return form.value.registrationStartTime && time < new Date(form.value.registrationStartTime)
}

// 类型路径映射
const buildPathMap = (nodes, parentPath = []) => {
  nodes.forEach(node => {
    const currentPath = [...parentPath, node.name]
    typePathMap.value[node.id] = currentPath.join(' / ')
    if (node.children) {
      buildPathMap(node.children, currentPath)
    }
  })
}

const getFullTypePath = (id) => {
  return typePathMap.value[id] || '未分类'
}

// 查看介绍
const formattedContent = computed(() => {
  if (!currentContent.value) return ''
  const rawHtml = marked.parse(currentContent.value)
  return DOMPurify.sanitize(rawHtml)
})

const handleViewContent = (content) => {
  currentContent.value = content
  contentDialogVisible.value = true
}

// 获取数据
const getList = () => {
  loading.value = true
  queryParams.value.params = {}
// 继续getList方法
  if (daterangeRegistrationStartTime.value?.length === 2) {
    queryParams.value.params.beginRegistrationStartTime = daterangeRegistrationStartTime.value[0]
    queryParams.value.params.endRegistrationStartTime = daterangeRegistrationStartTime.value[1]
  }
  if (daterangeRegistrationEndTime.value?.length === 2) {
    queryParams.value.params.beginRegistrationEndTime = daterangeRegistrationEndTime.value[0]
    queryParams.value.params.endRegistrationEndTime = daterangeRegistrationEndTime.value[1]
  }

  listActivity(queryParams.value).then(response => {
    activityList.value = response.rows
    total.value = response.total
    loading.value = false
  })
}

// 表单重置
const reset = () => {
  form.value = formDefaults()
  nextTick(() => {
    if (editorRef.value?.setContent) {
      editorRef.value.setContent('')
    } else if (window.tinymce?.activeEditor) {
      window.tinymce.activeEditor.setContent('')
    }
  })
  proxy.resetForm("activityRef")
}

// 取消对话框
const cancel = () => {
  open.value = false
  reset()
}

// 搜索
const handleQuery = () => {
  queryParams.value.pageNum = 1
  getList()
}

// 重置查询
const resetQuery = () => {
  daterangeRegistrationStartTime.value = []
  daterangeRegistrationEndTime.value = []
  proxy.resetForm("queryRef")
  handleQuery()
}

// 多选处理
const handleSelectionChange = (selection) => {
  ids.value = selection.map(item => item.id)
  single.value = selection.length !== 1
  multiple.value = !selection.length
}

// 新增
const handleAdd = () => {
  reset()
  open.value = true
  title.value = "添加活动"
}

// 修改
const handleUpdate = async (row) => {
  reset()
  const _id = row.id || ids.value[0]
  try {
    const res = await getActivity(_id)
    const data = res.data

    form.value = {
      ...data,
      registrationStartTime: formatDateString(data.registrationStartTime),
      registrationEndTime: formatDateString(data.registrationEndTime),
      startTime: formatDateString(data.startTime),
      endTime: formatDateString(data.endTime)
    }

    open.value = true
    title.value = "修改活动"
    nextTick(() => {
      if (editorRef.value?.setContent) {
        editorRef.value.setContent(form.value.content || '')
      }
    })
  } catch (error) {
    console.error('获取活动详情失败:', error)
    proxy.$modal.msgError("获取详情失败，请重试")
  }
}

// 提交表单
const submitForm = () => {
  proxy.$refs.activityRef.validate(valid => {
    if (valid) {
      const api = form.value.id ? updateActivity : addActivity
      const successMsg = form.value.id ? "修改成功" : "新增成功"

      api(form.value).then(() => {
        proxy.$modal.msgSuccess(successMsg)
        open.value = false
        getList()
      }).catch(error => {
        console.error('提交失败:', error)
        proxy.$modal.msgError("操作失败，请检查数据")
      })
    }
  })
}

// 删除
const handleDelete = (row) => {
  const _ids = row.id || ids.value
  proxy.$modal.confirm(`是否确认删除活动编号为"${_ids}"的数据项？`)
      .then(() => delActivity(_ids))
      .then(() => {
        getList()
        proxy.$modal.msgSuccess("删除成功")
      })
      .catch(error => {
        console.error('删除失败:', error)
        proxy.$modal.msgError("删除失败，请重试")
      })
}

// 导出
const handleExport = () => {
  proxy.download('activity/activity/export', {
    ...queryParams.value
  }, `activity_${new Date().getTime()}.xlsx`)
}

// 初始化类型数据
onMounted(async () => {
  try {
    const res = await listActivityType({ status: 0 })
    activityTypeTree.value = proxy.handleTree(res.data, "id", "parentId")
    buildPathMap(activityTypeTree.value)
    await getList()
  } catch (error) {
    console.error('初始化失败:', error)
    proxy.$modal.msgError("初始化数据失败")
  }
})

// 对话框关闭处理
const handleDialogClosed = () => {
  reset()
  dialogKey.value++
  editorKey.value++
}
</script>

<style lang="scss" scoped>
.app-container {
  :deep(.el-date-editor) {
    width: 100%;
  }

  .date-range {
    display: flex;
    flex-direction: column;
    gap: 8px;
  }

  .custom-dialog {
    .el-dialog__body {
      padding: 20px 25px;
    }

    .rich-editor {
      border: 1px solid #dcdfe6;
      border-radius: 4px;
      overflow: hidden;
    }
  }

  .markdown-dialog {
    .markdown-content {
      h1, h2, h3 {
        color: #333;
        margin: 1em 0 0.5em;
      }

      img {
        max-width: 100%;
        height: auto;
        margin: 10px 0;
        border-radius: 4px;
        box-shadow: 0 2px 12px 0 rgba(0,0,0,0.1);
      }

      pre {
        background: #f6f8fa;
        padding: 16px;
        border-radius: 4px;
        code {
          font-family: Monaco, Consolas, 'Courier New', monospace;
        }
      }
    }

    .custom-scrollbar {
      &::-webkit-scrollbar {
        width: 6px;
        height: 6px;
      }
      &::-webkit-scrollbar-thumb {
        border-radius: 3px;
        background: rgba(144,147,153,.3);
      }
    }
  }

  .w-full {
    width: 100%;
  }
}
</style>